package de.ludo.dao;

import java.util.ArrayList;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import de.ludo.entities.Game;
import de.ludo.entities.Highscore;
import de.ludo.entities.LudoSession;
import de.ludo.entities.Player;
import de.ludo.entities.User;
import de.ludo.gaming.PlayerType;
import de.ludo.util.GameType;

/**
 * Creates test data
 * 
 * @author L.Rother, Marlen Rotert, Felix, Gamze
 * 
 */
@Startup
@Singleton
public class LudoDataBuilder {

	@PersistenceContext
	EntityManager em;

	@Resource
	private String username1, username2, username3, username4, password1,
			password2, password3, password4;

	@EJB(beanName = "DAO", beanInterface = de.ludo.dao.DAOLocal.class)
	private DAOLocal dao;

	@PostConstruct
	private void init() {

		clearTempData();

		createUser();

	}

	/**
	 * Clears the temporary Data at the server start, to granite a consistent
	 * state
	 */
	private void clearTempData() {
		ArrayList<Game> games = dao.findAllGames();
		dao.closeAllGames(games);
		ArrayList<LudoSession> ludoSessions = dao.findAllLudoSessions();
		dao.closeAllLudoSessions(ludoSessions);
	}

	/**
	 * Standard user gamze, felix, lena, marlen
	 */
	private void createUser() {
		// user gamze
		User gamze = findOrCreateUser(username1, password1);
		Highscore hGamze = new Highscore(gamze.getUsername(), 10, GameType.Ludo);
		dao.saveHighscore(hGamze);

		// user marlen
		User marlen = findOrCreateUser(username2, password2);
		Highscore hMarlen = new Highscore(marlen.getUsername(), 7,
				GameType.Ludo);
		dao.saveHighscore(hMarlen);

		// user felix
		User felix = findOrCreateUser(username3, password3);
		Highscore hFelix = new Highscore(felix.getUsername(), 12, GameType.Ludo);
		dao.saveHighscore(hFelix);

		// user lena
		User lena = findOrCreateUser(username4, password4);
		Highscore hLena = new Highscore(lena.getUsername(), 15, GameType.Ludo);
		dao.saveHighscore(hLena);

		// User Lily
		User lily = findOrCreateUser("Lily", "Lily1");
		Highscore hLily = new Highscore(lily.getUsername(), 5, GameType.Ludo);
		dao.saveHighscore(hLily);

		User emma = findOrCreateUser("Emma", "Emma1");
		Highscore hEmma = new Highscore(emma.getUsername(), 8, GameType.Ludo);
		dao.saveHighscore(hEmma);

		User john = findOrCreateUser("John", "John1");
		Highscore hJohn = new Highscore(john.getUsername(), 2, GameType.Ludo);
		dao.saveHighscore(hJohn);

	}

	/**
	 * If the user not exists in DB, it will be created and returned. If it
	 * exists the user will be loaded and returned.
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	private User findOrCreateUser(String username, String password) {
		User user = em.find(User.class, username);
		if (user == null) {
			user = new User(username, password);
			em.persist(user);
		}
		return user;
	}

	/**
	 * If the session not exists in DB, it will be created and returned. If it
	 * exists the session will be loaded and returned.
	 * 
	 * @param user
	 * @return
	 */
	private LudoSession findOrCreateSession(User user) {
		LudoSession sessionUser = dao.findSessionByUserName(user.getUsername());
		if (sessionUser == null) {
			sessionUser = new LudoSession(user.getUsername());
			em.persist(sessionUser);
		}
		return sessionUser;
	}

	/**
	 * If the player not exists in DB, it will be created and returned. If it
	 * exists the player will be loaded and returned.
	 * 
	 * @param session
	 * @param playerType
	 * @return
	 */
	private Player findOrCreatePlayer(LudoSession session, PlayerType playerType) {
		Player player = em.find(Player.class, session.getId());
		if (player == null) {
			player = new Player(session, playerType);
			em.persist(player);
		}
		return player;
	}

}
